<!--
 * @FilePath     : /vision/src/components/Map.vue
 * @Author       : 哒哒哒
 * @Date         : 2024-05-24 16:25:19
 * @Description  :  商家分布(地图)
 * Copyright    : G AUTOMOBILE RESEARCH INSTITUTE CO.,LTD Copyright (c) 2024.
-->

<template>
    <div class="com-page" @dblclick="revertMap" :class="{'fullscreen': isFullScreen}">
        <!-- 返回按钮 -->
        <button @click="revertMap" v-if="!showChina" class="returnBtn">返回</button>
        <div class="com-container">
            <div class="com-chart" ref="map_ref"></div>
        </div>
        <!-- 右上角方法按钮   -->
        <FullSCreenIcon :isFullScreen="isFullScreen" @toggleFullScreen="changeFullScreen"></FullSCreenIcon>
    </div>
</template>

<script>
import { throttle } from '@/utils';
import { getProvinceMapInfo } from '@/utils/map_utils';
import axios from 'axios';
import FullSCreenIcon from './FullScreenIcon/index.vue'
import FullscreenMixin from './mixins/FullscreenMixin'
import ThemeMixins from '@/mixins/ThemeMixins';
export default {
    /* eslint-disable */
    name: 'Map',
    mixins: [FullscreenMixin, ThemeMixins],
    components: {
        FullSCreenIcon
    },
    data() {
        return {
            // 图标实例
            chartInstance: null,
            // 服务器返回的所有数据
            allData: null,
            // 记录监听事件，用于取消事件
            throttledAdaptScreen: null,
            // 省份地图数据记录,用于缓存,请求过的无需再请求
            mapData: {},
            // 是否现在展示的中国地图
            showChina: true,
        }
    },
    created() {
        this.$socket.registerCallback('mapData', this.getData)
        this.$socket.registerCallback('returnChina', this.returnChina)
        this.$socket.registerCallback('changeMap', this.changeMap)
    },
    async mounted() {
        this.initChart();
        this.$socket.send({
            action: 'getData',
            socketType: 'mapData',
            chartName: 'map',
            value: ''
        })
        this.adaptScreen();
        this.throttledAdaptScreen = throttle(this.adaptScreen, 100);
        window.addEventListener('resize', this.throttledAdaptScreen);
    },
    destroyed() {
        this.$socket.unRegisterCallback('returnChina')
        this.$socket.unRegisterCallback('changeMap')
        this.$socket.unRegisterCallback('mapData')
        clearInterval(this.timerId);
        window.removeEventListener('resize', this.throttledAdaptScreen)
    },
    methods: {
        // 回到中国地图
        revertMap() {
            this.$socket.send({
                action: 'changeMap',
                socketType: 'returnChina',
                chartName: 'Map',
                value: 'china'
            })
        },
        returnChina () {
            const revertOption = {
                geo: {
                    map: 'china'
                }
            }
            this.chartInstance.setOption(revertOption)
            this.showChina = true
        },
        // 初始化表格
        async initChart() {
            this.chartInstance = this.$echarts.init(this.$refs.map_ref, this.theme)
            // 获取数据
            let { data: mapData } = await axios.get('http://localhost:8999/static/map/china.json');
            // 注册地图
            this.$echarts.registerMap('china', mapData);
            const initOption = {
                title: {
                    text: '▎商家分布',
                    left: 20,
                    top: 20
                },
                geo: {
                    type: 'map',
                    map: 'china',
                    top: '5%',
                    bottom: '5%',
                    // 设置地图样式
                    itemStyle: {
                        // 设置地图的颜色
                        areaColor: '#2E72BF',
                        // 设置地图边界的颜色
                        borderColor: '#333'
                    }
                },
                legend: {
                    left: '5%',
                    bottom: '5%',
                    // 设置图例方向为竖直
                    orient: 'vertical'
                }
            }
            this.chartInstance.setOption(initOption)
            // 添加点击事件,实现点击跳转到省地图
            this.chartInstance.on('click', async (arg) => {
                this.$socket.send({
                    action: 'changeMap',
                    socketType: 'changeMap',
                    chartName: 'Map',
                    value: arg.name
                })
            })
        },
        async changeMap (mapName) {
            // 省一级的地图不再支持放大
            if (!this.showChina) return
            // arg只能获取到中文省份名字,根据中文身份获取到路径
            let provinceInfo = getProvinceMapInfo(mapName)
            if (!this.mapData[provinceInfo.key]) {
                let { data: provinceMapData } = await axios.get('http://localhost:8999' + provinceInfo.path);
                this.$echarts.registerMap(provinceInfo.key, provinceMapData);
                this.mapData[provinceInfo.key] = provinceMapData
            }
            const changeOption = {
                geo: {
                    map: provinceInfo.key
                }
            }
            this.chartInstance.setOption(changeOption)
            this.showChina = false;
        },
        // 获取数据
        async getData(data) {
            // const { data } = await this.$http.get('map')
            this.allData = data;
            // 渲染数据
            this.updateChart()
        },
        // 更新表格
        updateChart() {
            // 图例数组
            let legendArr = this.allData.map(item => item.name)
            // 该数组每一元素,代表一种类型的多个散点
            let seriesArr = this.allData.map((item) => ({
                // 散点
                type: 'effectScatter',
                // 设置涟漪效果
                rippleEffect: {
                    // 涟漪范围
                    scale: 5,
                    // 涟漪的效果
                    brushType: 'stroke'
                },
                // 该散点用于地图系统
                coordinateSystem: 'geo',
                // 用于lengend对应
                name: item.name,
                // 数据
                data: item.children,
            }))
            const dataOption = {
                legend: {
                    data: legendArr
                },
                series: seriesArr
            }
            this.chartInstance.setOption(dataOption)
        },
        // 根据屏幕尺寸，将图标适配屏幕
        adaptScreen() {
            let chartWidth = this.$refs.map_ref.offsetWidth;
            let fontSize = (chartWidth / 100) * 3.6
            const adaptOption = {
                title: {
                    textStyle: {
                        fontSize: fontSize
                    },
                },
                legend: {
                    itemWidth: fontSize / 2,
                    itemHeight: fontSize / 2,
                    itemGap: fontSize / 2,
                    textStyle: {
                        fontSize: fontSize / 2
                    }
                }
            }
            this.chartInstance.setOption(adaptOption)
            this.chartInstance.resize();
        }
    }
}
</script>

<style scoped lang='less'>
.returnBtn {
    position: absolute;
    right: 10%;
    top: 4%;
    z-index: 2;
}
</style>